package com.blue.firecat.utils.date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 描述 处理时间工具类
 * 时间 2017-6-23 17:48
 * 作者 肖亦鸣
 */
public class DateUtil {
    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);
    private static DateUtil instance;
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYY_DEL_MM_DEL_DD = "yyyy/MM/dd";
    public static final String YYYY_MM_DD_HHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYYMMDD = "yyyyMMdd";
    public static final String YYYY_MM_DD_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM_DD_HH_mm = "yyyy-MM-dd HH:mm";
    public static final String YYYYMMDDHHmmss = "yyyyMMddHHmmss";
    public static final String YYYYMMDDHHmmssSSS = "yyyyMMddHHmmssSSS";
    public static final String YYYY_MM = "yyyy-MM";
    public static final String XMXD_HH_mm = "M月d日 HH:mm";
    public static final String XMXDHH_mm = "M月d日HH:mm";
    public static final String HH_mm = "HH:mm";
    public static final String YYYY_MM_DD_HH = "yyyy-MM-dd HH";

    private DateUtil() {
    }

    public static DateUtil getInstance() {
        if (instance == null) {
            synchronized (DateUtil.class) {
                if (instance == null) {
                    instance = new DateUtil();
                }
            }
        }

        return instance;
    }

    public static Date getDateByFormatter(String sFormat, String date) {
        if (date != null && !"".equals(date)) {
            SimpleDateFormat formatter = new SimpleDateFormat(sFormat);

            try {
                return formatter.parse(date);
            } catch (ParseException var4) {
                logger.error("", var4);
                return null;
            }
        } else {
            return null;
        }
    }
    public static Date getDateByString(String date) {
        if (StringUtils.isNotEmpty(date)) {
            SimpleDateFormat formatter = new SimpleDateFormat(YYYY_MM_DD_HHMMSS);

            try {
                return formatter.parse(date);
            } catch (ParseException var4) {
                logger.error("", var4);
                return null;
            }
        } else {
            return null;
        }
    }
    public static String getCurrentDate_Simple() {
        Calendar rightNow = Calendar.getInstance();
        int year = rightNow.get(1);
        int month = rightNow.get(2) + 1;
        int day = rightNow.get(5);
        return convertDateToString(convertStringToDate(year + "-" + month + "-" + day));
    }

    public static Date getSecBeforeCurrentDate(int second) {
        Calendar c = Calendar.getInstance();
        c.add(13, -second);
        return c.getTime();
    }

    public static String getCurrentDate() {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(date);
    }

    public static String getCurrentDateShort() {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(date);
    }

    public static String getDateString(Date date) {
        if (date == null) {
            return "";
        } else {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return format.format(date);
        }
    }

    public static String getCurrentDate(String fm) {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat(fm);
        return format.format(date);
    }

    public static String getDateToString(Date time, String fm) {
        SimpleDateFormat format = new SimpleDateFormat(fm);
        return format.format(time);
    }

    public static String getDateByLongTime(long time) {
        Date date = new Date(time);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(date);
    }

    public static String getCurrentDateOrder() {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        return format.format(date);
    }

    public static String getCurrentDateTime() {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        return format.format(date);
    }

    public static String getMonthOfDayBeforeCurrentDate(int month) {
        Calendar c = Calendar.getInstance();
        c.add(2, -month);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static String getMonthOfDayAfterCurrentDate(int month) {
        Calendar c = Calendar.getInstance();
        c.add(2, -month);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static String getFirstDayOfCurrentMonth() {
        Calendar c = Calendar.getInstance();
        c.set(5, c.getActualMinimum(5));
        int year = c.get(1);
        int month = c.get(2) + 1;
        int day = c.get(5);
        return convertDateToString(convertStringToDate(year + "-" + month + "-" + day));
    }

    public static String getLastDayOfCurrentMonth() {
        Calendar c = Calendar.getInstance();
        c.set(5, c.getActualMaximum(5));
        int year = c.get(1);
        int month = c.get(2) + 1;
        int day = c.get(5);
        return convertDateToString(convertStringToDate(year + "-" + month + "-" + day));
    }

    public static String getFirstDayOfMonthString(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(5, c.getActualMinimum(5));
        int year = c.get(1);
        int month = c.get(2) + 1;
        int day = c.get(5);
        return convertDateToString(convertStringToDate(year + "-" + month + "-" + day));
    }

    public static Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(5, calendar.getActualMinimum(5));
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        return calendar.getTime();
    }

    public static String getLastDayOfMonthString(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(5, c.getActualMaximum(5));
        int year = c.get(1);
        int month = c.get(2) + 1;
        int day = c.get(5);
        return convertDateToString(convertStringToDate(year + "-" + month + "-" + day));
    }

    public static int getHour(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int hour = c.get(11);
        return hour;
    }

    public static int getDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int day = c.get(5);
        return day;
    }

    public static int getMinute() {
        Calendar c = Calendar.getInstance();
        int min = c.get(12);
        return min;
    }

    public static String getDayBeforeCurrentDate(int day) {
        Calendar c = Calendar.getInstance();
        c.add(5, -day);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static String getDayAfterCurrentDate(int day) {
        Calendar c = Calendar.getInstance();
        c.add(5, day);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static Date getDateTimeAfterCurrentDate(int day) throws ParseException {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        String newDate = getDayAfterCurrentDate(day);
        String time = format.format(date);
        SimpleDateFormat formatTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formatTime.parse(newDate + " " + time);
    }

    public static int getWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int week = c.get(7) - 1;
        return week;
    }

    public static String getWeekString(int week) {
        String strWeek;
        switch (week) {
            case 0:
                strWeek = "星期日";
                break;
            case 1:
                strWeek = "星期一";
                break;
            case 2:
                strWeek = "星期二";
                break;
            case 3:
                strWeek = "星期三";
                break;
            case 4:
                strWeek = "星期四";
                break;
            case 5:
                strWeek = "星期五";
                break;
            case 6:
                strWeek = "星期六";
                break;
            case 7:
                strWeek = "星期日";
                break;
            default:
                strWeek = "";
        }

        return strWeek;
    }

    public static String getWeekString(int week, int type) {
        if (type == 0) {
            return getWeekString(week);
        } else {
            String strWeek;
            switch (week) {
                case 0:
                    strWeek = "周日";
                    break;
                case 1:
                    strWeek = "周一";
                    break;
                case 2:
                    strWeek = "周二";
                    break;
                case 3:
                    strWeek = "周三";
                    break;
                case 4:
                    strWeek = "周四";
                    break;
                case 5:
                    strWeek = "周五";
                    break;
                case 6:
                    strWeek = "周六";
                    break;
                case 7:
                    strWeek = "周日";
                    break;
                default:
                    strWeek = "";
            }

            return strWeek;
        }
    }

    public static Date convertStringToDate(String strDate) {
        Date date = null;

        try {
            SimpleDateFormat e = new SimpleDateFormat("yyyy-MM-dd");
            date = e.parse(strDate);
        } catch (Exception var3) {
            logger.info("日期转换失败:" + var3.getMessage());
        }

        return date;
    }

    public static Date convertStringToDate(String strDate, String fm) {
        Date date = null;

        try {
            SimpleDateFormat e = new SimpleDateFormat(fm);
            date = e.parse(strDate);
        } catch (Exception var4) {
            logger.info("日期转换失败:" + var4.getMessage());
        }

        return date;
    }

    public static Date convertStringToDate2(String strDate) {
        Date date = null;

        try {
            SimpleDateFormat e = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            date = e.parse(strDate);
        } catch (Exception var6) {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");

            try {
                date = df.parse(strDate);
            } catch (ParseException var5) {
                logger.info("日期转换失败:" + var6.getMessage());
            }
        }

        return date;
    }

    public static boolean compareTwoDateBigOrSmall(String fromDate, String toDate) {
        Date dateFrom = convertStringToDate(fromDate);
        Date dateTo = convertStringToDate(toDate);
        return dateFrom.before(dateTo);
    }

    public static int compareDate(String Date1, String Date2) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Date date1 = df.parse(Date1);
            Date date2 = df.parse(Date2);
            if (date1.before(date2)) {
                return -1;
            }

            if (date1.equals(date2)) {
                return 0;
            }

            if (date1.after(date2)) {
                return 1;
            }
        } catch (ParseException var6) {
            logger.error("", var6);
        }

        return -2;
    }

    public static Calendar convertDateStringToCalendar(String strDate) {
        Date date = convertStringToDate(strDate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c;
    }

    public static Calendar convertDateToCalendar(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c;
    }

    public static String getDayOfMonthBeforeSpecificDate(String strDate, int month) {
        Calendar c = convertDateStringToCalendar(strDate);
        c.add(2, -month);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static String getDayOfHourBefore(String strDate, int hour) {
        try {
            SimpleDateFormat e = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = e.parse(strDate);
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(10, -hour);
            strDate = c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5) + " " + c.get(11) + ":" + c.get(14) + ":" + c.get(13);
        } catch (Exception var5) {
            logger.info("日期转换失败:" + var5.getMessage());
        }

        return strDate;
    }

    public static String getDayOfMonthAfterSpecificDate(String strDate, int month) {
        Calendar c = convertDateStringToCalendar(strDate);
        c.add(2, month);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static String getDayBeforeSpecificDate(String strDate, int day) {
        Calendar c = convertDateStringToCalendar(strDate);
        c.add(5, -day);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static String getDayAfterSpecificDate(String strDate, int day) {
        Calendar c = convertDateStringToCalendar(strDate);
        c.add(5, day);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public boolean isLeapYear() {
        Calendar rightNow = Calendar.getInstance();
        int year = rightNow.get(1);
        return 0 == year % 4 && (year % 100 != 0 || year % 400 == 0);
    }

    public Date convertStringToStandardDate(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dateTime = null;
        if (!"".equals(str)) {
            try {
                Date date = sdf.parse(str);
                dateTime = new Date(date.getTime());
            } catch (ParseException var6) {
                logger.error("", var6);
            }
        }

        return dateTime;
    }

    public static String convertDateToString(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(date);
    }

    public static String convertDateToString(Date date, String dateformat) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(dateformat);
        return dateFormat.format(date);
    }

    public static String convertDateToString_str(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        return dateFormat.format(date);
    }

    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return "";
        } else {
            if (pattern == null || "".equals(pattern)) {
                pattern = "yyyy-MM-dd";
            }

            SimpleDateFormat dateFormat;
            try {
                dateFormat = new SimpleDateFormat(pattern);
                return dateFormat.format(date);
            } catch (Exception var4) {
                dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                return dateFormat.format(date);
            }
        }
    }

    public static int getMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(2) + 1;
        return month;
    }

    public static int getYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int year = c.get(1);
        return year;
    }

    public static String getPreHour(String format, int step) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Calendar cal = Calendar.getInstance();
        cal.set(10, cal.get(10) - step);
        return sdf.format(cal.getTime());
    }

    public static String getPrevMonthOfDate(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(convertStringToDate(date));
        cal.add(2, -1);
        return sdf.format(cal.getTime());
    }

    public static String getNextMonthOfDate(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(convertStringToDate(date));
        cal.add(2, 1);
        return sdf.format(cal.getTime());
    }

    public static Hashtable<Integer, Integer> getWeekNumberHT(long beginDate, long endDate) {
        Hashtable weeks = new Hashtable();

        for (int q = 1; q <= 7; ++q) {
            weeks.put(Integer.valueOf(q), Integer.valueOf(0));
        }

        for (long var10 = beginDate; var10 <= endDate; var10 += (new Long(86400000L)).longValue()) {
            Calendar c = Calendar.getInstance();
            Date date = new Date(var10);
            c.setTime(date);
            int dayofweek = c.get(7) - 1;
            if (dayofweek == 0) {
                dayofweek = 7;
            }

            if (weeks.containsKey(Integer.valueOf(dayofweek))) {
                weeks.put(Integer.valueOf(dayofweek), Integer.valueOf(((Integer) weeks.get(Integer.valueOf(dayofweek))).intValue() + 1));
            } else {
                weeks.put(Integer.valueOf(dayofweek), Integer.valueOf(1));
            }
        }

        return weeks;
    }

    public static String getPrevWeekOfDate(String date) {
        return getDayBeforeSpecificDate(date, 7);
    }

    public static int getLastDayOfMonth(int year, int month) {
        return month != 1 && month != 3 && month != 5 && month != 7 && month != 8 && month != 10 && month != 12 ? (month != 4 && month != 6 && month != 9 && month != 11 ? (month == 2 ? (isLeapYear(year) ? 29 : 28) : 0) : 30) : 31;
    }

    public static boolean isLeapYear(int year) {
        return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    }

    public static List<String> getDaysByFromTo(String beginDateStr, String endDateStr) {
        Date beiginDate = convertStringToDate(beginDateStr);
        endDateStr = getDayAfterSpecificDate(endDateStr, 1);
        Date endDate = convertStringToDate(endDateStr);
        ArrayList dateList = new ArrayList();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date currentDate = new Date();
        if (currentDate.before(beiginDate)) {
            currentDate = beiginDate;
        }

        for (String currentDateStr = sdf.format(currentDate); currentDate.before(endDate); currentDate = convertStringToDate(currentDateStr)) {
            dateList.add(currentDateStr);
            currentDateStr = getDayAfterSpecificDate(currentDateStr, 1);
        }

        return dateList;
    }

    public static String getAfterMinute(String minute) {
        Long m = Long.valueOf(Long.parseLong(minute) * 60L * 1000L);
        return getDateByLongTime(System.currentTimeMillis() + m.longValue(), "MM-dd HH:mm");
    }

    public static String getDateByLongTime(long time, String fm) {
        Date date = new Date(time);
        SimpleDateFormat format = new SimpleDateFormat(fm);
        return format.format(date);
    }

    public static int formatCalendar(Calendar cal) {
        int year = cal.get(1);
        int month = cal.get(2) + 1;
        int day = cal.get(5);
        int date = year * 10000 + month * 100 + day;
        return date;
    }

    public static int getWeekday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return getWeekday(cal);
    }

    public static int getWeekday(String dateStr, String format) {
        Date date = convertStringToDate(dateStr, format);
        return getWeekday(date);
    }

    public static int getWeekday(Calendar cal) {
        int weekday = cal.get(7);
        if (weekday == 1) {
            weekday = 7;
        } else {
            --weekday;
        }

        return weekday;
    }

    public static String convertInt8ToString(int date) {
        return String.format("%04d", new Object[]{Integer.valueOf(date / 10000)}) + "-" + String.format("%02d", new Object[]{Integer.valueOf(date / 100 % 100)}) + "-" + String.format("%02d", new Object[]{Integer.valueOf(date % 100)});
    }

    public static String getYueSaoDayBeforeSpecificDate(String strDate, int day) {
        Calendar c = convertDateStringToCalendar(strDate);
        c.add(5, day);
        return convertDateToString(convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5)));
    }

    public static Double getTimeDifference(String startdate, String enddate) throws Exception {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = df.parse(startdate);
        Date d2 = df.parse(enddate);
        long diff = d2.getTime() - d1.getTime();
        double hour = (double) diff / 3600000.0D;
        return Double.valueOf(hour);
    }

    public static int getTimeDifference(Date startDate, Date endDate) throws Exception {
        long diff = endDate.getTime() - startDate.getTime();
        double hour = (double) diff / 3600000.0D;
        return (int) Math.floor(hour);
    }

    public static int getDayDifference(Date startDate, Date endDate) throws Exception {
        Calendar startcal = Calendar.getInstance();
        startcal.setTime(startDate);
        Calendar endcal = Calendar.getInstance();
        endcal.setTime(endDate);
        long time = endcal.getTimeInMillis() - startcal.getTimeInMillis();
        int days = (new Long(time / 86400000L)).intValue();
        return days;
    }

    public static Date calculateDate(String date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            return df.parse(date);
        } catch (ParseException var3) {
            logger.error("日期转换错误", var3);
            return null;
        }
    }

    public static Date getDayAfterCurrentDateByDate(int day) {
        Calendar c = Calendar.getInstance();
        c.add(5, day);
        return convertStringToDate("" + c.get(1) + "-" + (c.get(2) + 1) + "-" + c.get(5));
    }

    public static String getDayAfterCurrentDateNew(int day) {
        Calendar c = Calendar.getInstance();
        c.add(5, day);
        return c.get(2) + 1 + "." + c.get(5);
    }

    public static Date getFirstDayOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayWeek = cal.get(7);
        System.out.println(dayWeek);
        if (1 == dayWeek) {
            cal.add(5, -1);
        }

        cal.setFirstDayOfWeek(2);
        int day = cal.get(7);
        cal.add(5, cal.getFirstDayOfWeek() - day);
        return cal.getTime();
    }

    public static Date getDelayDate(Integer day) {
        Calendar cal = Calendar.getInstance();
        cal.add(5, day.intValue());
        return cal.getTime();
    }
}
